import { sendMsgApi } from '@renderer/api/chat'
import useUser from '@renderer/pinai/modules/user'
import useOptions from '@renderer/pinai/modules/options'
import useChat from '@renderer/pinai/modules/chat'
class socket {
  socket: WebSocket
  url: string
  TO: any
  user: any
  optionStore: any
  useStore: any
  chatStore: any
  constructor(url: string) {
    this.url = url
    this.socket = new WebSocket(url)
    this.useStore = useUser()
    this.optionStore = useOptions()
    this.chatStore = useChat()
    this.socket.onopen = this.onOpen
    this.socket.onmessage = this.onMessage
    this.socket.onclose = this.onClose
    this.socket.onerror = this.onError
    this.user = this.useStore.userInfo
  }
  onOpen = (event: Event) => {
    console.log(event)
  }
  onMessage = (event: MessageEvent) => {
    const data = JSON.parse(event.data)
    console.log('收到消息', data)
    const msg = data.data.msg
    switch (msg) {
      case 'newFriend':
        // 当新朋友添加我的时候触发
        this.updateFriendApplyNum()
        break
      case 'ok':
        // 成功接收到好友的消息
        this.handleOnMessage(data.data.message)
        break
      case 'offline':
        // 离线消息
        this.handleOnMessage(data.data.message.message)
        console.log('离线消息')
      default:
        break
    }
  }
  // 关闭连接
  onClose = (event: CloseEvent) => {
    console.log('WebSocket 断开连接', event)
    this.TO = null
  }
  // 发生错误
  onError = (event: Event) => {
    console.log('WebSocket 发送错误', event)
    this.TO = null
  }
  // 组织信息格式
  formatSendData(params) {
    return {
      id: 0, // 唯一id，后端生成，用于撤回指定消息
      friend_id: params.friend_id, // 好友在朋友表中的id
      from_avatar: this.user.avatar, // 发送者头像
      from_name: this.user.nickname || this.user.username, // 发送者昵称
      from_id: this.user.id, // 发送者id
      to_id: params.to_id || this.TO.id, // 接收人/群 id
      to_name: params.to_name || this.TO.name, // 接收人/群 名称
      to_avatar: params.to_avatar || this.TO.avatar, // 接收人/群 头像
      chat_type: params.chat_type || this.TO.chat_type, // 接收类型
      type: params.type, // 消息类型
      data: params.data, // 消息内容
      options: params.options ? params.options : {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      sendStatus: 'pending' // 发送状态，success发送成功,fail发送失败,pending发送中
    }
  }
  // 会话列表的中发送的消息和接受的消息展示的格式
  formatChatItemData(message) {
    let data = message.data
    switch (message.type) {
      case 'emo':
        data = '[表情]'
        break
      case 'image':
        data = '[图片]'
        break
      case 'audio':
        data = '[语音]'
        break
      case 'video':
        data = '[视频]'
        break
      case 'card':
        data = '[名片]'
        break
    }
    data = message.chat_type === 'group' ? `${message.from_name}:${data}` : data
    return data
  }
  // 创建聊天对象
  createChatObject(params) {
    /*
			id: 好友id或群id
			name: 接收人/群 名称
			avatar: 好友头像或者群头像
			chat_type: 群聊group或私聊user
		**/
    this.TO = params
    console.log('创建聊天对象', this.TO)
  }
  // 当新朋友添加我的时候触发, 更新朋友提示数量
  updateFriendApplyNum() {
    // this.socket.send()
    this.optionStore.setNewFriendApplyNum()
  }
  // 获取本地存储会话列表
  getChatList() {
    const key = `chatlist_${this.user.id}`
    return localStorage.getItem(key)
  }
  // 数组置顶
  listToFirst(arr, index) {
    let topiingNum = 0
    arr.forEach((f) => {
      if (f.isTopping) {
        topiingNum += 1
      }
    })
    if (index != 0) {
      if (topiingNum === 0) {
        arr.unshift(arr.splice(index, 1)[0])
      } else {
        const oldItem = arr.splice(index, 1)[0]
        arr.splice(topiingNum, 0, oldItem)
      }
    }
    return arr
  }
  // 获取聊天记录
  getChatDetail(key) {
    const k = key
      ? key
      : `chatDetail_${this.user.id}_${this.TO.chat_type}_${this.TO.id}`
    return JSON.parse(localStorage.getItem(k) || '[]')
  }
  // 处理接受到的消息
  handleOnMessage(message) {
    console.log(message)
    // 将消息添加到消息记录
    this.addHistoryRecord(message, false)
    this.chatStore.getMessageList(
      this.user.id,
      message.from_id,
      message.chat_type
    )
    // 更新会话列表
    this.updateChatList(message, false)
  }
  // 添加到历史记录
  addHistoryRecord(message, isSend = true) {
    // 1. 获取对方id
    const id =
      message.chat_type === 'user'
        ? isSend
          ? message.to_id
          : message.from_id
        : message.to_id
    // 2. 存放缓存的key值：chatDetail_当前用户id_会话类型_接收人/群id
    const key = `chatDetail_${this.user.id}_${message.chat_type}_${id}`
    // 3. 读取缓存
    const list = this.getChatDetail(key as any)
      ? this.getChatDetail(key as any)
      : ([] as any)
    // 3. 添加标识 后续修改消息状态
    message.k = 'k' + list?.length
    list?.push(message)
    // 4. 重新设置缓存
    localStorage.setItem(key, JSON.stringify(list))
    return {
      data: message,
      k: message.k
    }
  }
  // 更新指定历史记录
  async updateChatDetail(message, k, isSend = true) {
    // 获取对方id
    const id =
      message.chat_type === 'user'
        ? isSend
          ? message.to_id
          : message.from_id
        : message.to_id
    // key值：chatDetail_当前用户id_会话类型_接收人/群id
    const key = `chatDetail_${this.user.id}_${message.chat_type}_${id}`
    // 获取原来的聊天记录
    const list = this.getChatDetail(key as any)
      ? this.getChatDetail(key as any)
      : ([] as any)
    // 根据k查找对应聊天记录
    const index = list?.findIndex((item) => item.k === k)
    if (index === -1) return
    list[index] = message
    // 存储
    localStorage.setItem(key, JSON.stringify(list))
  }
  // 发送消息
  sendMsg(message) {
    return new Promise((resolve, reject) => {
      //  添加消息历史记录
      const { k } = this.addHistoryRecord(message)
      // 更新会话列表
      this.updateChatList(message)
      // 发送消息
      sendMsgApi(message)
        .then((res: any) => {
          message.id = res.id
          message.sendStatus = 'success'
          // 更新指定历史记录
          this.updateChatDetail(message, k)
          resolve(message)
        })
        .catch(() => {
          message.sendStatus = 'fail'
          // 更新指定历史记录
          this.updateChatDetail(message, k)
          reject(message)
        })
    })
  }
  // 更新本地存储会话列表
  updateChatList(message, isSend = true) {
    console.log(message, 'message')
    // 获得本地的会话列表
    let list = JSON.parse(this.getChatList() || '[]')
    // 记录是否处于当前聊天中  如果是发送消息后就不会跟新角标
    let isCurrentChat = false
    // 接收人/群 id/头像/昵称
    let id = 0
    let avatar = ''
    let name = ''
    if (message.chat_type === 'user') {
      // 聊天对象是否存在
      isCurrentChat = this.TO
        ? isSend
          ? this.TO.id === message.to_id
          : this.TO.id === message.from_id
        : false
      id = isSend ? message.to_id : message.from_id
      avatar = isSend ? message.to_avatar : message.from_avatar
      name = isSend ? message.to_name : message.from_name
    } else {
      isCurrentChat = this.TO && this.TO.id === message.to_id
      id = message.to_id
      avatar = message.to_avatar
      name = message.to_name
    }
    // 会话是否存在 不存在则创建到头部 存在则更新提前到头部
    const index = list.findIndex((item) => {
      return item.chat_type === message.chat_type && item.id === id
    })
    console.log(index, 'index')
    //  未读数是否 + 1
    const noreadnum = isSend || isCurrentChat ? 0 : 1
    // 消息的展示格式
    const lastData = this.formatChatItemData(message)
    if (index !== -1) {
      // 存在
      // 拿到当前会话
      const item = list[index]
      // 更新该会话最后一条消息时间，内容，类型
      item.update_time = new Date().getTime()
      item.name = name
      item.data = lastData
      item.avatar = avatar
      item.type = message.type
      // 未读数更新
      item.noreadnum += noreadnum
      // 置顶会话
      list = this.listToFirst(list, index)
    } else {
      // 不存在
      let chatItem = {
        id, // 接收人/群 id
        friend_id: message.friend_id, // 好友在朋友表中的id
        chat_type: message.chat_type, // 接收类型 user单聊 group群聊
        avatar, // 接收人/群 头像
        name, // 接收人/群 昵称
        update_time: new Date().getTime(), // 最后一条消息的时间戳
        data: lastData, // 最后一条消息内容
        type: message.type, // 最后一条消息类型
        noreadnum, // 未读数
        istop: false, // 是否置顶
        shownickname: false, // 是否显示昵称
        nowarn: false, // 消息免打扰
        strongwarn: false, // 是否开启强提醒
        isTopping: false, // 是否置顶
        user_id: 0, // 群管理员id
        remark: '', //群公告
        invite_confirm: 1 // 邀请确认
      }
      // 群聊
      if (message.chat_type === 'group' && message.group) {
        chatItem.shownickname = true
        chatItem.name = message.to_name
        chatItem = {
          ...chatItem,
          user_id: message.group.user_id, // 群管理员id
          remark: '', // 群公告
          invite_confirm: 1 // 邀请确认
        }
      }
      list.unshift(chatItem)
    }
    // 跟新显示的会话列表
    this.chatStore.addSessionChatList(list)
    //  更新未读数
    return list
  }
}

export default socket
